import type { InternalNamePath, NamePath } from '../interface';
type SimilarObject = string | number | object;
export function isSimilar(source: SimilarObject, target: SimilarObject) {
  if (source === target) {
    return true;
  }

  if ((!source && target) || (source && !target)) {
    return false;
  }

  if (
    !source ||
    !target ||
    typeof source !== 'object' ||
    typeof target !== 'object'
  ) {
    return false;
  }

  const sourceKeys = Object.keys(source); // Object.keys(Array) === index组成的数组
  const targetKeys = Object.keys(target);
  const keys = new Set([...sourceKeys, ...targetKeys]);

  return [...(keys as any)].every((key) => {
    const sourceValue = (source as any)[key];
    const targetValue = (target as any)[key];

    if (
      typeof sourceValue === 'function' &&
      typeof targetValue === 'function'
    ) {
      return true;
    }
    return sourceValue === targetValue;
  });
}

/**
 * Convert name to internal supported format.
 * This function should keep since we still thinking if need support like `a.b.c` format.
 * 'a' => ['a']
 * 123 => [123]
 * ['a', 123] => ['a', 123]
 */
export function nameToNamePath(path?: NamePath): InternalNamePath {
  if (!path) {
    return [];
  }

  return Array.isArray(path) ? path : [path];
}

/**
 *
 *
 * @export
 * @param {any[]} array [0,1,2,3]
 * @param {number} from 1
 * @param {number} to  2
 * @returns [0,2,1,3]
 */
export function arrayItemMove(array: any[], from: number, to: number) {
  if (
    from < 0 ||
    from >= array.length ||
    to < 0 ||
    to >= array.length ||
    from === to
  ) {
    return array;
  }

  const arrayFromItem = array.splice(from, 1)[0];
  array.splice(to, 0, arrayFromItem);
  return array;
}

/**
 *
 *
 * @export
 * @param {*} args
 */
export function defaultGetValueFromEvent(valuePropName: string, event: any) {
  //event.target: 事件触发对象(鼠标点击对象)
  if (
    event &&
    event.target &&
    typeof event.target === 'object' &&
    valuePropName in event.target
  ) {
    return event.target[valuePropName];
  }
  return event;
}
